package com.weme.common.util;

import static com.luck.picture.lib.thread.PictureThreadUtils.runOnUiThread;
import static com.qiniu.pili.droid.shortvideo.PLErrorCode.ERROR_LOW_MEMORY;
import static com.qiniu.pili.droid.shortvideo.PLErrorCode.ERROR_NO_VIDEO_TRACK;
import static com.qiniu.pili.droid.shortvideo.PLErrorCode.ERROR_SRC_DST_SAME_FILE_PATH;

import android.content.Context;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.util.Log;

import androidx.core.content.FileProvider;

import com.qiniu.pili.droid.shortvideo.PLShortVideoTranscoder;
import com.qiniu.pili.droid.shortvideo.PLVideoSaveListener;
import com.weme.common.BaseApplication;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class VideoCompressUtils {
    private boolean isCompressing;
    private long startTime;
    private float percentage;
    public static final String LOCAL_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();

    public interface IAddCompressDateListener {//创建抽象类

        void dateBank(String s);

        void errorBean(String s);
    }

    /**
     * 获取手机相册路径
     *
     * @return
     */
    public static String getCameraPath(Context context) {
        String cameraPath = context.getExternalCacheDir().getAbsolutePath()
                + "/Camera";
        File file = new File(cameraPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        return cameraPath;
    }

    public static void startCompressed(Context context, String videoPath, IAddCompressDateListener obb) {

        //PLShortVideoTranscoder初始化，三个参数，第一个context，第二个要压缩文件的路径，第三个视频压缩后输出的路径
        long timecurrentTimeMillis = System.currentTimeMillis();
        PLShortVideoTranscoder mShortVideoTranscoder = new PLShortVideoTranscoder(context, videoPath, getCameraPath(context) + "/" + timecurrentTimeMillis + "transcoded.mp4");
        MediaMetadataRetriever retr = new MediaMetadataRetriever();
        Uri userPickedUri;
        try {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
                userPickedUri = Uri.fromFile(new File(videoPath));
            } else {
                userPickedUri = FileProvider.getUriForFile(context, BaseApplication.sInstance.getPackageName() + ".FileProvider", new File(videoPath));
            }
            //   userPickedUri = Uri.fromFile(new File(videoPath));

            retr.setDataSource(context, userPickedUri);
        } catch (Exception e) {
            obb.errorBean(videoPath);
            return;
        }

        String height = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); // 视频高度
        String width = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); // 视频宽度
        String rotation = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION); // 视频旋转方向
        int transcodingBitrateLevel = 6;
        Disposable disposable = Observable.interval(20, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    mShortVideoTranscoder.cancelTranscode();
                });

        mShortVideoTranscoder.transcode(Integer.parseInt(width), Integer.parseInt(height), getEncodingBitrateLevel(transcodingBitrateLevel), false, new PLVideoSaveListener() {
            @Override
            public void onSaveVideoSuccess(String s) {
                Log.e("snow", "save onSaveVideoSuccess: " + s);
                obb.dateBank(s);
                disposable.dispose();

//                runOnUiThread(new Runnable() {
//                    @Override
//                    public void run() {
//                        LogUtil.e("onSaveVideoSuccess======== " + s);
//                    }
//                });
            }

            @Override
            public void onSaveVideoFailed(final int errorCode) {
                obb.errorBean(videoPath);
                disposable.dispose();
                Log.e("snow", "save failed: " + errorCode);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        switch (errorCode) {
                            case ERROR_NO_VIDEO_TRACK:
//                                ToastUtils.getInstance().showToast("该文件没有视频信息！");
                                break;
                            case ERROR_SRC_DST_SAME_FILE_PATH:
//                                ToastUtils.getInstance().showToast("源文件路径和目标路径不能相同！");
                                break;
                            case ERROR_LOW_MEMORY:
//                                ToastUtils.getInstance().showToast("手机内存不足，无法对该视频进行时光倒流！");
                                break;
                            default:
//                                ToastUtils.getInstance().showToast("transcode failed: " + errorCode);
                        }
                    }
                });
            }

            @Override
            public void onSaveVideoCanceled() {
                obb.errorBean(videoPath);
                disposable.dispose();
//                LogUtil.e("onSaveVideoCanceled");
            }

            @Override
            public void onProgressUpdate(float percentag) {
                Log.e("snow", percentag + "");
//                LogUtil.e("onProgressUpdate==========" + percentage);
            }
        });
    }


    public static void startCompressedStore(Context context, String videoPath, IAddCompressDateListener obb) {

        //PLShortVideoTranscoder初始化，三个参数，第一个context，第二个要压缩文件的路径，第三个视频压缩后输出的路径
        long timecurrentTimeMillis = System.currentTimeMillis();
        PLShortVideoTranscoder mShortVideoTranscoder = new PLShortVideoTranscoder(context, videoPath, getCameraPath(context) + "/" + timecurrentTimeMillis + "transcoded.mp4");
        MediaMetadataRetriever retr = new MediaMetadataRetriever();
        Uri userPickedUri;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            userPickedUri = Uri.fromFile(new File(videoPath));
        } else {
            userPickedUri = FileProvider.getUriForFile(context, BaseApplication.sInstance.getPackageName() + ".FileProvider", new File(videoPath));
        }
        //   userPickedUri = Uri.fromFile(new File(videoPath));
        try {
            retr.setDataSource(context, userPickedUri);
        } catch (IllegalArgumentException e) {
            obb.errorBean(videoPath);
            return;
        }

        String height = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); // 视频高度
        String width = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); // 视频宽度
        String rotation = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION); // 视频旋转方向
        int transcodingBitrateLevel = 6;
        Disposable disposable = Observable.interval(20, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    mShortVideoTranscoder.cancelTranscode();
                });
        try {
            mShortVideoTranscoder.transcode(Integer.parseInt(width), Integer.parseInt(height), getEncodingBitrateLevel(transcodingBitrateLevel), false, new PLVideoSaveListener() {
                @Override
                public void onSaveVideoSuccess(String s) {
                    Log.e("snow", "save onSaveVideoSuccess: " + s);
                    obb.dateBank(s);
                    disposable.dispose();

//                runOnUiThread(new Runnable() {
//                    @Override
//                    public void run() {
//                        LogUtil.e("onSaveVideoSuccess======== " + s);
//                    }
//                });
                }

                @Override
                public void onSaveVideoFailed(final int errorCode) {
                    obb.errorBean(videoPath);
                    disposable.dispose();
                    Log.e("snow", "save failed: " + errorCode);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            switch (errorCode) {
                                case ERROR_NO_VIDEO_TRACK:
//                                ToastUtils.getInstance().showToast("该文件没有视频信息！");
                                    break;
                                case ERROR_SRC_DST_SAME_FILE_PATH:
//                                ToastUtils.getInstance().showToast("源文件路径和目标路径不能相同！");
                                    break;
                                case ERROR_LOW_MEMORY:
//                                ToastUtils.getInstance().showToast("手机内存不足，无法对该视频进行时光倒流！");
                                    break;
                                default:
//                                ToastUtils.getInstance().showToast("transcode failed: " + errorCode);
                            }
                        }
                    });
                }

                @Override
                public void onSaveVideoCanceled() {
                    obb.errorBean(videoPath);
                    disposable.dispose();
//                LogUtil.e("onSaveVideoCanceled");
                }

                @Override
                public void onProgressUpdate(float percentag) {
                    Log.e("snow", percentag + "");
//                LogUtil.e("onProgressUpdate==========" + percentage);
                }
            });
        } catch (NumberFormatException e) {
            obb.errorBean("");
        }

    }


    /**
     * 设置压缩质量
     *
     * @param position
     * @return
     */
    private static int getEncodingBitrateLevel(int position) {
        return ENCODING_BITRATE_LEVEL_ARRAY[position];
    }

    /**
     * 选的越高文件质量越大，质量越好,对应压缩后尺寸更大
     */
    public static final int[] ENCODING_BITRATE_LEVEL_ARRAY = {
            500 * 1000,
            800 * 1000,
            1000 * 1000,
            1200 * 1000,
            1600 * 1000,
            2000 * 1000,
            2500 * 1000,
            4000 * 1000,
            8000 * 1000,
    };


    /**
     * 获取指定文件大小
     *
     * @return
     * @throws Exception
     */
    private static long getFileSize(File file) {
        long size = 0;
        try {
            if (file.exists()) {
                FileInputStream fis = null;
                fis = new FileInputStream(file);
                size = fis.available();
            } else {
                file.createNewFile();
                Log.e("获取文件大小", "文件不存在!");
            }
            return size;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return size;
    }

    /**
     * 格式化单位
     *
     * @param size
     */

    public String getFormatSize(double size) {
        double kiloByte = size / 1024;
        if (kiloByte < 1) {
            return size + "MB";
        }
        double megaByte = kiloByte / 1024;
//        if (megaByte < 1) {
//
//            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
//            return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
//        }
        double gigaByte = megaByte / 1024;
        if (gigaByte < 1) {
            BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
        }
        double teraBytes = gigaByte / 1024;
        if (teraBytes < 1) {
            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
        }
        BigDecimal result4 = new BigDecimal(teraBytes);
        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
    }




}
